From f3e43bfced8ec8822d0d2c51d6a5532410ed305a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 24 Jul 2014 12:30:47 -0700 Subject: [PATCH] Ensure LD_LIBRARY_PATH is correct for plugins At runtime rustc will dlopen() plugins, and if plugins have dynamic dependencies they're likely to be in target/deps, so we need to make sure that directory is in the right search path. --- src/cargo/ops/cargo_rustc/mod.rs | 17 +++++-- tests/test_cargo_compile_plugins.rs | 73 +++++++++++++++++++++++++++++ tests/tests.rs | 1 + 3 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 tests/test_cargo_compile_plugins.rs diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index c4b319973..605b7c884 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -1,5 +1,7 @@ -use std::io::{fs, UserRWX}; use std::collections::HashSet; +use std::dynamic_lib::DynamicLibrary; +use std::io::{fs, UserRWX}; +use std::os; use semver::Version; use core::{Package, PackageId, PackageSet, Target, Resolve}; @@ -145,7 +147,7 @@ fn compile_custom(pkg: &Package, cmd: &str, // be building a C lib for a plugin let layout = cx.layout(false); let output = layout.native(pkg); - let mut p = process(cmd.next().unwrap(), pkg) + let mut p = process(cmd.next().unwrap(), pkg, cx) .env("OUT_DIR", Some(&output)) .env("DEPS_DIR", Some(&output)) .env("TARGET", cx.config.target()); @@ -204,7 +206,7 @@ fn rustc(package: &Package, target: &Target, fn prepare_rustc(package: &Package, target: &Target, crate_types: Vec<&str>, cx: &Context, req: PlatformRequirement) -> Vec { - let base = process("rustc", package); + let base = process("rustc", package, cx); let base = build_base_args(base, target, crate_types.as_slice()); let target_cmd = build_plugin_args(base.clone(), cx, false); @@ -355,9 +357,16 @@ fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package, } } -pub fn process(cmd: T, pkg: &Package) -> ProcessBuilder { +pub fn process(cmd: T, pkg: &Package, cx: &Context) -> ProcessBuilder { + // When invoking a tool, we need the *host* deps directory in the dynamic + // library search path for plugins and such which have dynamic dependencies. + let mut search_path = DynamicLibrary::search_path(); + search_path.push(cx.layout(false).deps().clone()); + let search_path = os::join_paths(search_path.as_slice()).unwrap(); + util::process(cmd) .cwd(pkg.get_root()) + .env(DynamicLibrary::envvar(), Some(search_path.as_slice())) .env("CARGO_PKG_VERSION_MAJOR", Some(pkg.get_version().major.to_string())) .env("CARGO_PKG_VERSION_MINOR", Some(pkg.get_version().minor.to_string())) .env("CARGO_PKG_VERSION_PATCH", Some(pkg.get_version().patch.to_string())) diff --git a/tests/test_cargo_compile_plugins.rs b/tests/test_cargo_compile_plugins.rs new file mode 100644 index 000000000..98396c8e5 --- /dev/null +++ b/tests/test_cargo_compile_plugins.rs @@ -0,0 +1,73 @@ +use std::os; +use std::path; + +use support::{project, execs, basic_bin_manifest}; +use support::{RUNNING, COMPILING}; +use hamcrest::{assert_that, existing_file}; +use cargo::util::process; + +fn setup() { +} + +test!(plugin_to_the_max { + let foo = project("foo") + .file("Cargo.toml", r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.bar] + path = "../bar" + "#) + .file("src/main.rs", r#" + #![feature(phase)] + #[phase(plugin)] extern crate bar; + + fn main() {} + "#); + let bar = project("bar") + .file("Cargo.toml", r#" + [package] + name = "bar" + version = "0.0.1" + authors = [] + + [[lib]] + name = "bar" + plugin = true + + [dependencies.baz] + path = "../baz" + "#) + .file("src/lib.rs", r#" + #![feature(plugin_registrar)] + + extern crate rustc; + extern crate baz; + + use rustc::plugin::Registry; + + #[plugin_registrar] + pub fn foo(reg: &mut Registry) { + println!("{}", baz::baz()); + } + "#); + let baz = project("baz") + .file("Cargo.toml", r#" + [package] + name = "baz" + version = "0.0.1" + authors = [] + + [[lib]] + name = "baz" + crate_type = ["dylib"] + "#) + .file("src/lib.rs", "pub fn baz() -> int { 1 }"); + bar.build(); + baz.build(); + + assert_that(foo.cargo_process("cargo-build"), + execs().with_status(0)); +}) diff --git a/tests/tests.rs b/tests/tests.rs index 80ca230b8..a77d451f2 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -30,3 +30,4 @@ mod test_cargo_cross_compile; mod test_cargo_run; mod test_cargo_version; mod test_cargo_new; +mod test_cargo_compile_plugins; -- 2.30.2